package com.nclg.exam.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nclg.exam.dto.*;
import com.nclg.exam.entity.TQuestion;
import com.nclg.exam.entity.TUser;
import com.nclg.exam.service.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

@RestController
public class PageController {

    @Autowired
    private UserService userService;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private PaperService paperService;

    @Autowired
    private UserPaperService userPaperService;

    @Autowired
    private ExamService examService;

    /**
     * 登录页面
     * @return
     */
    @GetMapping("/toLogin")
    public ModelAndView login(){
        return new ModelAndView("/login");
    }

    /**
     * 注册页面
     * @return
     */
    @GetMapping("/toRegister")
    public ModelAndView register(){
        return new ModelAndView("/register");
    }

    /**
     * 首页
     * @return
     */
    @GetMapping("/index")
    public ModelAndView index(HttpServletRequest request){
        //如果用户修改个人信息返回首页时，防止tUser返回shiro中的信息
        if (null != request.getSession().getAttribute("tUser")) return new ModelAndView("/index");
        //如果session中没有tUser，则表示刚刚登陆，从shiro的session中获取用户信息
        Subject subject = SecurityUtils.getSubject();
        TUser tUser = (TUser) subject.getPrincipal();
        request.getSession().setAttribute("tUser", tUser);
        return new ModelAndView("/index");
    }

    /**
     * 后台页面
     * @return
     */
    @GetMapping("/backstage")
    public ModelAndView backstage(){
        return new ModelAndView("/admin/backstage");
    }

    /**
     * 修改个人信息页面
     * @return
     */
    @GetMapping("/updateMy")
    public ModelAndView updateMy(){
        return new ModelAndView("/user/update");
    }

    /**
     * 修改密码页面
     * @return
     */
    @GetMapping("/updatePwd")
    public ModelAndView updatePwd(){
        return new ModelAndView("/user/updatePwd");
    }

    /**
     * 正在考试列表页面
     * @return
     */
    @GetMapping("/userExamList")
    public ModelAndView userExamList(){
        return new ModelAndView("/exam/userExamList");
    }

    /**
     * 考试页面
     * @return
     */
    @GetMapping("/examing/{pid}/{pname}/{endtime}")
    public ModelAndView examing(@PathVariable String pid,
                                @PathVariable String pname,
                                @PathVariable String endtime,
                                HttpServletRequest request) {
        Long pId = Long.valueOf(pid);
        boolean isTrue = paperService.selectIsExamingById(pId);
        if (!isTrue) {
            ModelAndView mv = new ModelAndView("/error");
            mv.addObject("msg", "请从正常途径进入考试页面");
            mv.addObject("code", 404);
            String url = request.getRequestURI();
            try {
                url=java.net.URLDecoder.decode(new String(url.getBytes("ISO-8859-1"), "UTF-8"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            mv.addObject("url", url);
            return mv;
        }
        List<ExamQuestionDto> questions = questionService.selectQuestionByPid(pId);
        String time = endtime.replaceAll("-", "/");
        ModelAndView mv = new ModelAndView("/exam/examing");
        mv.addObject("pname", pname);
        mv.addObject("pid", pId);
        mv.addObject("endtime", time);
        mv.addObject("questions", questions);
        return mv;
    }

    /**
     * 学生历史考卷列表页面
     * @return
     */
    @GetMapping("/userPaperList")
    public ModelAndView userPaperList(){
        return new ModelAndView("/exam/userPaperList");
    }

    /**
     * 学生历史考卷信息
     * @param upid
     * @return
     */
    @GetMapping("/examFinishedInfo/{upid}")
    public ModelAndView examFinishedInfo(@PathVariable String upid){
        ModelAndView mv = userPaperInfo(upid);
        mv.setViewName("/exam/examFinishedInfo");
        return mv;
    }

    /**
     * 抽取方法
     * 学生历史考卷信息
     * @return
     */
    public ModelAndView userPaperInfo(String upid){
        Long upId = Long.valueOf(upid);
        //查询用户考卷信息
        UserPaperFinishedDto paper = userPaperService.selectById(upId);

        //查询试卷题目
        List<ExamQuestionDto> questions = questionService.selectQuestionByPid(paper.getPId());

        //查询用户答案
        String answer = examService.selectUserAnswer(paper.getUpId());

        ObjectMapper mapper = new ObjectMapper();
        List<AnswerDto> answers = new ArrayList<>();
        try {
            answers = mapper.readValue(answer, new TypeReference<List<AnswerDto>>() {});
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        ModelAndView mv = new ModelAndView();
        mv.addObject("paper", paper);
        mv.addObject("questions", questions);
        mv.addObject("answers", answers);

        return mv;
    }

    /**
     * 用户列表管理页面
     * @return
     */
    @GetMapping("/userList")
    public ModelAndView userList(){
        return new ModelAndView("/admin/userList");
    }

    /**
     * 修改他人信息页面
     * @param uid
     * @return
     */
    @GetMapping("/updateOther/{uid}")
    public ModelAndView updateOther(@PathVariable String uid){
        TUser user = userService.selectByPrimaryKey(Long.valueOf(uid));
        return new ModelAndView("/admin/updateOther", "user", user);
    }

    /**
     * 添加用户页面
     * @return
     */
    @GetMapping("/addUser")
    public ModelAndView addUser(){
        return new ModelAndView("/admin/addUser");
    }

    /**
     * 题库管理
     * @return
     */
    @GetMapping("/questionList")
    public ModelAndView questionList(){
        List<CreaterDto> list = questionService.selectCreaters();
        return new ModelAndView("/admin/questionList", "creaters", list);
    }

    /**
     * 添加题目
     * @return
     */
    @GetMapping("/addQuestion")
    public ModelAndView addQuestion(){
        return new ModelAndView("/admin/addQuestion");
    }

    /**
     * 编辑题目
     * @param qid
     * @return
     */
    @GetMapping("/updateQuestion/{qid}")
    public ModelAndView updateQuestion(@PathVariable String qid){
        TQuestion question = questionService.selectById(Long.valueOf(qid));
        return new ModelAndView("/admin/updateQuestion", "question", question);
    }

    /**
     * 试卷管理
     * @return
     */
    @GetMapping("/paperList")
    public ModelAndView paperList(){
        List<CreaterDto> list = paperService.selectCreaters();
        return new ModelAndView("/admin/paperList", "creaters", list);
    }

    /**
     * 编辑试卷
     * @param pid
     * @return
     */
    @GetMapping("/updatePaper/{pid}")
    public ModelAndView updatePaper(@PathVariable String pid){
        UpdatePaperDto paperInfo  = paperService.selectById(Long.valueOf(pid));
        return new ModelAndView("/admin/updatePaper", "paperInfo", paperInfo);
    }

    /**
     * 创建试卷
     * @return
     */
    @GetMapping("/addPaper")
    public ModelAndView addPaper(){
        return new ModelAndView("/admin/addPaper");
    }

    /**
     * 阅卷管理
     * @return
     */
    @GetMapping("/markingList")
    public ModelAndView markingList(){
        List<CreaterDto> list = userPaperService.selectExaminers();
        return new ModelAndView("/admin/markingList", "examiners", list);
    }

    /**
     * 阅卷
     * @param upid
     * @return
     */
    @GetMapping("/reviewPaper/{upid}")
    public ModelAndView reviewPaper(@PathVariable String upid){
        ModelAndView mv = userPaperInfo(upid);
        mv.setViewName("/admin/reviewPaper");
        return mv;
    }
}
